#pragma once
#include <vector>

namespace RETURN_STATUS
{
	enum{RETURN_OK = 0, RETURN_NEEDMOREDATA = 1, RETURN_ERROR = -1,RETURN_EXCEPTION = -2};
};

/*[blk header]
 *01 00 00 00  03 00 00 00  00 00 00 00  01 00 00 00
 *
 *[IN_buffer, pBase]
 *4D 01 00 00  05 02 00 00  ............
 *
 *[OUT_buffer, pBase]
 *44 01 00 00  05 02 00 00 	............
 */
class BufferData_ParserBase
{
public:
	BufferData_ParserBase(){};
	virtual ~BufferData_ParserBase(){};
protected:
	void ParseData(const char* IN pBase, unsigned int IN offset, unsigned int IN length,  char* OUT pOUT);
};

class FuncData_ParserBase : public BufferData_ParserBase
{
protected:
	FuncData_ParserBase();
	enum{PARAMCOUNT_OFFSET = 0x24, 
		PARAMBLK_OFFSET = 0x38, 
		TIME_OFFSET = 0x19, 
		FUNCID_OFFSET = 0x2C,
	};

public:
	virtual ~FuncData_ParserBase() = 0;

	virtual int Getvalue(const char* IN pBase,std::string&) = 0;

protected:
	/* pBase: IN buffer or OUT buffer base address, the buffer is already tailored to a func data
	 *theNO: the 0-indexed param to be parsed
	 * nlength:
	 *     [IN]: pValue buffer length
	 *     [OUT]: the real value length
	 */
	void ParseFuncParam(const char* IN pBase, unsigned int IN theIndex, char* OUT pValue, unsigned int& INOUT nlength);

};

/************************************************************************/
/* pStart is the start address of current InBuffer or OutBuffer, i.e. the blk header */
/* is NOT in the buffer                                                 */
/************************************************************************/
class general_InOutBuffer_parser:public FuncData_ParserBase
{
public:
	general_InOutBuffer_parser();
	virtual ~general_InOutBuffer_parser();
public:
	virtual int Getvalue(const char* IN pBase,std::string&){return RETURN_STATUS::RETURN_ERROR; };
	/* pStart: the first byte address of current In Buffer
	 * pEnd:
	 *    [IN]: the last byte address + 1 of current buffer
	 *	  [OUT]: the last byte address + 1 of current func InBuffer
	 * [RETURN]:
	 *        0:
	 *       >0: 
	 */
	virtual int MoveToEnd(const char* IN pStart, char*& INOUT pEnd);
};

// class general_OutBuffer_parser:public FuncData_ParserBase
// {
// public:
// 	general_OutBuffer_parser();
// 	virtual ~general_OutBuffer_parser();
// public:
// 	/* pStart: the first byte address of current func OutBuffer 
// 	 *         mostly, it is the pEnd returned by general_InBuffer_parser.MoveToEnd
// 	 * pEnd:
// 	 *    [IN]: the last byte address + 1 of current buffer
// 	 *	  [OUT]: the last byte address + 1 of current func OutBuffer
// 	 */
// 	int MoveToEnd(const void* IN pStart, void*& INOUT pEnd);
// };

class blocktype
{
public:
	blocktype():low_(0),high_(0){};
	blocktype(unsigned int low, unsigned int high):low_(low),high_(high){};

	~blocktype(){};
	bool operator == (const blocktype& r) const{return (low_ == r.low_)&&(high_ == r.high_);};
public:
	void setValue(unsigned int low, unsigned int high){low_ = low; high_ = high;};
protected:
	unsigned int low_;
	unsigned int high_;
};

class blocktype_parser:public BufferData_ParserBase
{
public:
	blocktype_parser(){};
	virtual ~blocktype_parser(){};
public:
	int GetBlockType(const char* IN pBlkBase, blocktype&);
};

/************************************************************************/
/* pBase is the start address of current InBuffer or OutBuffer,        */
/* i.e. the blk header is NOT in the buffer                             */
/*                                                                      */
/************************************************************************/
class functime_parser:public FuncData_ParserBase
{
public:
	functime_parser(){};
	virtual ~functime_parser(){};
public:
	virtual int Getvalue(const char* IN pBase,std::string&);

	int GetTime(const char* IN pBase, SYSTEMTIME&);
};

/************************************************************************/
/* pBase is the start address of current InBuffer or OutBuffer,        */
/* i.e. the blk header is NOT in the buffer                             */
/*                                                                      */
/************************************************************************/
class paramcount_parser:public FuncData_ParserBase
{
public:
	paramcount_parser(){};
	virtual ~paramcount_parser(){};
public:
	virtual int Getvalue(const char* IN pBase,std::string&);
	int GetParamCount(const char* IN pBase, unsigned int&);

};

// class outparamcount_parser:public FuncData_ParserBase
// {
// public:
// 	outparamcount_parser();
// 	virtual ~outparamcount_parser();
// public:
// 	int GetParamCount(const void* IN pBase, unsigned int&);
// };

// class stoptime_parser:public FuncData_ParserBase
// {
// public:
// 	stoptime_parser();
// 	virtual ~stoptime_parser();
// public:
// 	int GetTime(const void* IN pBase, SYSTEMTIME&);
// };

class funcid_parser:public FuncData_ParserBase
{
public:
	funcid_parser(){};
	virtual ~funcid_parser(){};
public:
	virtual int Getvalue(const char* IN pBase,std::string&){return RETURN_STATUS::RETURN_ERROR;};
	int GetFuncId(const char* IN pBase, unsigned int&);

};

class funcNestedParam_parser : public FuncData_ParserBase
{
public:
	funcNestedParam_parser(const std::string& , int nIndex, int type );
	virtual ~funcNestedParam_parser(){};
	enum{VALUETYPE_INT, VALUETYPE_STR};

	virtual int Getvalue(const char* IN pBase,std::string&);
private:
	std::string paramName_;

	/*if the paramIndex_ == -1, the last papam is returned
	 *	
	 */
	int paramIndex_;
	int type_;
};

/************************************************************************/
/* for write or read                                                    */
/************************************************************************/
class funcIOBufNestedParam_parser : public FuncData_ParserBase
{
public:
	funcIOBufNestedParam_parser(const std::string& , unsigned int nIndex);
	virtual ~funcIOBufNestedParam_parser(){};

public:
	virtual int Getvalue(const char* IN pBase,std::string&);
protected:
	std::string paramName_;
	unsigned int paramIndex_;
};



// class ud_parser:public FuncData_ParserBase
// {
// public:
// 	ud_parser();
// 	virtual ~ud_parser();
// public:
// 	virtual int Getvalue(const void* IN pBase,std::string&);
// };
// 
// class udname_parser:public FuncData_ParserBase
// {
// public:
// 	udname_parser();
// 	virtual ~udname_parser();
// public:
// 	int Getvalue(const void* IN pBase,std::string&);
// 
// };
// 
// class in_cntl_parser:public FuncData_ParserBase
// {
// public:
// 	in_cntl_parser();
// 	virtual ~in_cntl_parser();
// public:
// 	int Getvalue(const void* IN pBase,std::string&);
// 
// };

/************************************************************************/
/* pBase is the start address of current InBuffer,                      */
/* i.e. the blk header is NOT in the buffer                             */
/*                                                                      */
/************************************************************************/
class wrtbuf_parser:public FuncData_ParserBase
{
public:
	wrtbuf_parser(){};
	virtual ~wrtbuf_parser(){};
public:
	int Getvalue(const char* IN pBase,std::string&);

};


/************************************************************************/
/* pBase is the start address of current OutBuffer,                      */
/*                                                                      */
/************************************************************************/
class rbuf_parser:public FuncData_ParserBase
{
public:
	rbuf_parser(){};
	virtual ~rbuf_parser(){};
public:
	int Getvalue(const char* IN pBase,std::string&);

};

// class ibsta_parser:public FuncData_ParserBase
// {
// public:
// 	ibsta_parser();
// 	virtual ~ibsta_parser();
// public:
// 	int Getvalue(const void* IN pBase,std::string&);
// 
// };
// 
// class ibcntl_parser:public FuncData_ParserBase
// {
// public:
// 	ibcntl_parser();
// 	virtual ~ibcntl_parser();
// public:
// 	int Getvalue(const void* IN pBase,std::string&);
// 
// };


/************************************************************************/
/* condition                                                            */
/************************************************************************/
class condition
{
public:
	condition(const std::vector<unsigned int>& );
	~condition(){};
public:
	bool operator()(const char* pInBufStart, const char* pOutBufStart,  funcNestedParam_parser* = NULL ) const;
protected:
	funcNestedParam_parser devidparser_;
	std::vector<unsigned int> devids_;

};
